home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / WINGs / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-05  |  4.6 KB  |  245 lines

  1. /*
  2.  *  Window Maker miscelaneous function library
  3.  * 
  4.  *  Copyright (c) 1997 Alfredo K. Kojima
  5.  * 
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21.  
  22. #include "../src/config.h"
  23.  
  24. #include "WUtil.h"
  25.  
  26. #include <stdlib.h>
  27. #include <sys/types.h>
  28. #include <unistd.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <assert.h>
  32. #include <signal.h>
  33.  
  34. #ifdef TEST_WITH_GC
  35. #include <gc/gc.h>
  36. #endif
  37.  
  38. #ifndef False
  39. # define False 0
  40. #endif
  41. #ifndef True
  42. # define True 1
  43. #endif
  44.  
  45.  
  46. static void
  47. defaultHandler(int bla)
  48. {
  49.     if (bla)
  50.     kill(getpid(), SIGABRT);
  51.     else
  52.     exit(1);
  53. }
  54.  
  55.  
  56. static waborthandler *aborthandler = (waborthandler*)defaultHandler;
  57.  
  58. #define wAbort(a) (*aborthandler)(a)
  59.  
  60.  
  61. waborthandler*
  62. wsetabort(waborthandler *handler)
  63. {
  64.     waborthandler *old = aborthandler;
  65.  
  66.     aborthandler = handler;
  67.  
  68.     return old;
  69. }
  70.  
  71.  
  72.  
  73. static int Aborting=0; /* if we're in the middle of an emergency exit */
  74.  
  75.  
  76. static WMHashTable *table = NULL;
  77.  
  78.  
  79. void *wmalloc(size_t size)
  80. {
  81.     void *tmp;
  82.  
  83. #ifdef TEST_WITH_GC
  84.     tmp = GC_malloc(size);
  85. #else
  86.     tmp = malloc(size);
  87. #endif
  88.     if (tmp == NULL) {
  89.     wwarning("malloc() failed. Retrying after 2s.");
  90.     sleep(2);
  91. #ifdef TEST_WITH_GC
  92.         tmp = GC_malloc(size);
  93. #else
  94.         tmp = malloc(size);
  95. #endif
  96.     if (tmp == NULL) {
  97.         if (Aborting) {
  98.         fputs("Really Bad Error: recursive malloc() failure.", stderr);
  99.         exit(-1);
  100.         } else {
  101.         wfatal("virtual memory exhausted");
  102.         Aborting=1;
  103.         wAbort(False);
  104.         }
  105.     }
  106.     }
  107.     return tmp;
  108. }
  109.  
  110.  
  111. void *wrealloc(void *ptr, size_t newsize)
  112. {
  113.     void *nptr;
  114.  
  115.     if (!ptr) {
  116.     nptr = wmalloc(newsize);
  117.     } else if (newsize==0) {
  118.         wfree(ptr);
  119.         nptr = NULL;
  120.     } else {
  121. #ifdef TEST_WITH_GC
  122.     nptr = GC_realloc(ptr, newsize);
  123. #else
  124.     nptr = realloc(ptr, newsize);
  125. #endif
  126.         if (nptr==NULL) {
  127.             wwarning("realloc() failed. Retrying after 2s.");
  128.             sleep(2);
  129. #ifdef TEST_WITH_GC
  130.             nptr = GC_realloc(ptr, newsize);
  131. #else
  132.             nptr = realloc(ptr, newsize);
  133. #endif
  134.             if (nptr == NULL) {
  135.                 if (Aborting) {
  136.                     fputs("Really Bad Error: recursive realloc() failure.",
  137.                           stderr);
  138.                     exit(-1);
  139.                 } else {
  140.                     wfatal("virtual memory exhausted");
  141.                     Aborting=1;
  142.                     wAbort(False);
  143.                 }
  144.             }
  145.         }
  146.     }
  147.     return nptr;
  148. }
  149.  
  150.  
  151. void*
  152. wretain(void *ptr)
  153. {
  154.     int *refcount;
  155.     
  156.     if (!table) {
  157.     table = WMCreateHashTable(WMIntHashCallbacks);
  158.     }
  159.         
  160.     refcount = WMHashGet(table, ptr);
  161.     if (!refcount) {
  162.     refcount = wmalloc(sizeof(int));
  163.     *refcount = 1;
  164.     WMHashInsert(table, ptr, refcount);
  165. #ifdef VERBOSE
  166.     printf("== %i (%p)\n", *refcount, ptr);
  167. #endif
  168.     } else {
  169.     (*refcount)++;
  170. #ifdef VERBOSE
  171.     printf("+ %i (%p)\n", *refcount, ptr);
  172. #endif
  173.     }
  174.     
  175.     return ptr;
  176. }
  177.  
  178.  
  179.  
  180. void
  181. wfree(void *ptr)
  182. {
  183. #ifdef TEST_WITH_GC
  184.     GC_free(ptr);
  185. #else
  186.     free(ptr);
  187. #endif
  188. }
  189.  
  190.  
  191.  
  192. void
  193. wrelease(void *ptr)
  194. {
  195.     int *refcount;
  196.     
  197.     refcount = WMHashGet(table, ptr);
  198.     if (!refcount) {
  199.     wwarning("trying to release unexisting data %p", ptr);
  200.     } else {
  201.     (*refcount)--;
  202.     if (*refcount < 1) {
  203. #ifdef VERBOSE
  204.         printf("RELEASING %p\n", ptr);
  205. #endif
  206.         WMHashRemove(table, ptr);
  207.         wfree(refcount);
  208.         wfree(ptr);
  209.     }
  210. #ifdef VERBOSE
  211.     else {
  212.         printf("- %i (%p)\n", *refcount, ptr);
  213.     }
  214. #endif
  215.     }
  216. }
  217.  
  218.  
  219. char*
  220. wstrdup(char *str)
  221. {
  222.     assert(str!=NULL);
  223.  
  224.     return strcpy(wmalloc(strlen(str)+1), str);
  225. }
  226.  
  227.  
  228. char*
  229. wstrappend(char *dst, char *src)
  230. {
  231.     char *str;
  232.     
  233.     if (!dst)
  234.     return wstrdup(src);
  235.     else if (!src)
  236.     return wstrdup(dst);
  237.     
  238.     str = wmalloc(strlen(dst)+strlen(src)+1);
  239.     strcpy(str, dst);
  240.     strcat(str, src);
  241.  
  242.     return str;
  243. }
  244.  
  245.